/*******************************************************************************************
 *      @name   mutex.c
 *      @brief  这是在多线程编程使用互斥锁实现对临界资源的访问，目的是学习线程的同步互斥的机制
 *      @date   2025/02/14
 *      @author cecelmx@126.com 
 *      @note
 *              1.互斥锁也称为互斥量/互斥体，linux系统的互斥锁必须要进行初始化
 *              2.对于互斥锁的应该包含上锁/解锁，应该访问临界资源的时候先上锁，再访问，最后再解锁
 * 
 *      @version  xx.xx.xx   主版本号.次版本号.修正版本号
 * 
 *      CopyRight (c)   2024-2025   Your Name     All Right Reserved
 * 
 * ****************************************************************************************/

#include <time.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

//假设创建子线程用于获取当前系统时间并转化为固定格式的字符串，存储到缓冲区，主线程从缓冲区中读取字符串

//临界资源，访问的应该互斥访问
char timebuf[128] = {0}; //用于记录转化好的系统时间  "2025/2/13 hh:mm:ss"

//定义互斥量，用于多线程间的互斥访问，该互斥量的属性是默认的，已经初始化过的
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 


//构造线程的回调函数 格式是固定的
void *thread1_handler(void *arg)
{
    for(;;)
    {
        //上锁操作
        pthread_mutex_lock(&mutex);

        //获取系统时间
        time_t ptime = time(NULL); //以秒为单位

        //转化系统时间
        struct tm *ptm = localtime(&ptime);
        sprintf(timebuf,"date:%d/%d/%d,time:%02d-%02d-%02d",
                                                        ptm->tm_year+1900,
                                                        ptm->tm_mon+1,
                                                        ptm->tm_mday,
                                                        ptm->tm_hour,
                                                        ptm->tm_min,
                                                        ptm->tm_sec                                           
        
                                                    );     
        //解锁操作
        pthread_mutex_unlock(&mutex);
        
        sleep(1);
    }
    
}


//构造线程的回调函数 格式是固定的
void *thread2_handler(void *arg)
{
    int i = 0;
    for(;;)
    {  
        //上锁操作
        pthread_mutex_lock(&mutex);

        sprintf(timebuf,"hello world [%d]",i++);

        //解锁操作
        pthread_mutex_unlock(&mutex);

        sleep(1);
    }
    
}

int main()
{
   
    pthread_t newthread1_id = 0;                //用于记录创建的新线程的ID，可以理解为是线程的句柄
    pthread_t newthread2_id = 0;                //用于记录创建的新线程的ID，可以理解为是线程的句柄


    //1.创建新线程
    pthread_create(&newthread1_id,NULL,thread1_handler,NULL);
    pthread_create(&newthread2_id,NULL,thread2_handler,NULL);
    
    //主线程的任务
    for(;;)
    {
        //上锁操作
        pthread_mutex_lock(&mutex);

        //显示系统时间
        printf("%s\n",timebuf);

        //解锁操作
        pthread_mutex_unlock(&mutex);

        sleep(1);
    }

    return 0;
}

